package com.project.common.screens;

import java.io.UnsupportedEncodingException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.PixelFormat;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.text.method.PasswordTransformationMethod;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.project.trac.R;

import core.communication.IMService;
import core.interfaces.IAppManager;
import core.modules.DatabaseConnector;
import core.modules.Institute;

public class Login2 extends Institute {

	private ResultSet rs;

	private EditText inputUsername;
	private EditText inputPassword;
	private EditText inputCode;

	private Dialog dialog;
	private AlertDialog.Builder alertDialog;
	private ProgressDialog progressDialog;

	private TextView msg;
	private TextView create;
	private TextView spiel;
	private View layout;

	// String required for login
	private String INPUT_USERNAME;
	private String INPUT_PASSWORD;
	private String INPUT_CODE;
	int ctr = 0;

	private String USERNAME;
	private String PASSWORD;
	private String IDENTIFIER;
	
    private IAppManager imService;
	
    protected static final int NOT_CONNECTED_TO_SERVICE = 0;
	protected static final int FILL_BOTH_USERNAME_AND_PASSWORD = 1;
	protected static final int MAKE_SURE_USERNAME_AND_PASSWORD_CORRECT = 2 ;
	protected static final int NOT_CONNECTED_TO_NETWORK = 3;
	public static final String AUTHENTICATION_FAILED = "0";
	public static final String FRIEND_LIST = "FRIEND_LIST";

	 private ServiceConnection mConnection = new ServiceConnection() {
	        public void onServiceConnected(ComponentName className, IBinder service) {
	            // This is called when the connection with the service has been
	            // established, giving us the service object we can use to
	            // interact with the service.  Because we have bound to a explicit
	            // service that we know is running in our own process, we can
	            // cast its IBinder to a concrete class and directly access it.
	            imService = ((IMService.IMBinder)service).getService();  
	            
	            if (imService.isUserAuthenticated() == true)
	            {
					startActivity(new Intent(Login2.this, Dashboard.class));
					Login2.this.finish();
	            }
	        }

	        public void onServiceDisconnected(ComponentName className) {
	            // This is called when the connection with the service has been
	            // unexpectedly disconnected -- that is, its process crashed.
	            // Because it is running in our same process, we should never
	            // see this happen.
	        	imService = null;
	            Toast.makeText(Login2.this, R.string.local_service_stop,
	                    Toast.LENGTH_SHORT).show();
	        }
	    };
	
	@Override
	protected void onPause() {
		unbindService(mConnection);
		super.onPause();
	}

	@Override
	protected void onResume() {
		bindService(new Intent(Login2.this, IMService.class), mConnection,
				Context.BIND_AUTO_CREATE);

		super.onResume();
	}
	    
	    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.commons_login);
		setTitle("TRAC Login");
		
		final ConnectivityManager conManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
		final NetworkInfo wifi = conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		final CheckBox showPassword = (CheckBox) findViewById(R.id.showpassword);
		final Button btnLogin = (Button) findViewById(R.id.buttonLogin);

		// Custom Dialog Layout
		layout = View.inflate(getApplicationContext(), R.layout.generic_dialog_box, null);
		inputCode = (EditText) layout.findViewById(R.id.dialogInput);
		spiel = (TextView) layout.findViewById(R.id.dialogSpiel);
		create = (TextView) findViewById(R.id.createStudentAccount);
		spiel.setText("For faculty members, authorization code is required.");

		progressDialog = new ProgressDialog(Login2.this);
		alertDialog = new AlertDialog.Builder(Login2.this);
		msg = new TextView(this);

		alertDialog.setTitle("Information").setIcon(android.R.drawable.ic_dialog_info);
		alertDialog.setCancelable(true);

		msg.setTextAppearance(this, R.style.alert_message);
		msg.setGravity(Gravity.CENTER_HORIZONTAL);

		// Pre-check for connectivity
//		if (!wifi.isAvailable()) {
//			msg.setText("Please check Wifi hardware availability");
//			alertDialog.setView(msg)
//			.setCancelable(false)
//			.setPositiveButton(android.R.string.ok,
//					new DialogInterface.OnClickListener() {
//				public void onClick(DialogInterface dialog,int id) {
//					Login.this.finish();
//				}
//			}).create().show();
//
//		} else if (wifi.isAvailable() && !wifi.isConnected()) {
//			msg.setText("An internet connection is required to login!");
//			alertDialog.setView(msg)
//			.setPositiveButton(android.R.string.ok,
//					new DialogInterface.OnClickListener() {
//				// FIXME invoke fix wifi setting
//				public void onClick(DialogInterface dialog, int id) {
//					dialog.dismiss();
//				}
//			}).create().show();
//
//		} else if (wifi.isAvailable() && wifi.isConnected()) {

			new AsynchronousTask("validate").execute();
			startService(new Intent(Login2.this,  IMService.class));	

//		}

		alertDialog.setPositiveButton("I'm a teacher!", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				INPUT_CODE = inputCode.getText().toString();
				if (IDENTIFIER.equals(INPUT_CODE)) {
					inputCode.setText("");
					startActivity(new Intent(Login2.this, Registration.class).putExtra("TAG_IDENTIFIER", "0"));
					
				} else {
					Toast.makeText(getBaseContext(), "Invalid faculty code.", Toast.LENGTH_LONG).show();
					inputCode.setText("");
					ctr++;
					if (ctr == 3) {
						msg.setText("Invalid faculty code for 3 times, \n system shutdown");
						alertDialog.setTitle("Alert!");
						alertDialog.setIcon(android.R.drawable.ic_dialog_alert);
						alertDialog.setView(msg);
						alertDialog.setNegativeButton(android.R.string.ok,new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface arg0, int arg1) {
								finish();
							}
						});

					}
				} //end if-else
			}
		});
		alertDialog.setNegativeButton("I'm a student!", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				INPUT_CODE = inputCode.getText().toString();
				if (INPUT_CODE.isEmpty()) {
					startActivity(new Intent(Login2.this, Registration.class).putExtra("TAG_IDENTIFIER", "1"));
				} else {
					Toast.makeText(getBaseContext(), "No need for a faculty code.", Toast.LENGTH_LONG).show();
					inputCode.setText("");
					dialog.cancel();
				}
			}
		});

		dialog = alertDialog.setTitle("New Registration").setView(layout).create();

		create.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				dialog.show();
			}
		});

		showPassword.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {
				if (((CheckBox) showPassword).isChecked()) {
					inputPassword.setTransformationMethod(null);
				} else {
					inputPassword.setTransformationMethod(new PasswordTransformationMethod());
				}
			}
		});

		inputUsername = (EditText) findViewById(R.id.editusername);
		inputPassword = (EditText) findViewById(R.id.editpassword);

		btnLogin.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				INPUT_USERNAME =  inputUsername.getText().toString();
				INPUT_PASSWORD = inputPassword.getText().toString();

				List<EditText> e = new ArrayList<EditText>();
				e.add(inputPassword);
				e.add(inputUsername);

				for (EditText et : e) {
					if (et.getText().toString().length() == 0) {
						et.requestFocus();
						et.setError("Field is empty!");
					}
				}

				if (imService == null) {
					showDialog(NOT_CONNECTED_TO_SERVICE);
					return;
				}
				else if (imService.isNetworkConnected() == false)
				{
					showDialog(NOT_CONNECTED_TO_NETWORK);
					
				}
					
			}
		});

	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
		super.onSaveInstanceState(outState);
	}

	private long lastPress;
	@Override
	public void onBackPressed() {

		long currentTime = System.currentTimeMillis();
		if (currentTime - lastPress > 3500) {
			Toast.makeText(getBaseContext(), "Press back again to exit.", Toast.LENGTH_LONG).show();
			lastPress = currentTime;
		} else {
			finish();
		}

		if (dialog.isShowing()) {
			this.inputCode.setText("");
		}
	}

	@Override
	public void onAttachedToWindow() {
		super.onAttachedToWindow();
		Window window = getWindow();
		window.setFormat(PixelFormat.RGBA_8888);
	}

	private class AsynchronousTask extends AsyncTask<String, String, String> {

		String command = " ";
		AsynchronousTask(String command)
		{
			doInBackground(command);
			this.command = command;
		}

		protected void onPreExecute() {
			super.onPreExecute();
			progressDialog.setTitle("Please Wait");

			if (this.command.equalsIgnoreCase("login")) {
				progressDialog.setMessage("Validating credentials...");
			} else {
				progressDialog.setMessage("Initializing connection...");
			}

			progressDialog.setIcon(android.R.drawable.ic_dialog_info);
			progressDialog.setIndeterminate(true);
			progressDialog.setCancelable(true);
			progressDialog.show();

		}

		protected String doInBackground(String... args) {

			try {

				if (command.equalsIgnoreCase("validate")) {
					rs = DatabaseConnector.getStatement().executeQuery("SELECT * FROM code");
					while (rs.next()) {
						IDENTIFIER = rs.getString("identifier");
					}
				}

				if (command.equalsIgnoreCase("login")) {

					rs = DatabaseConnector.getStatement().executeQuery
							("SELECT id, FirstName, username, password, isstudent FROM users WHERE username = '" 
									+ INPUT_USERNAME + "' AND password = '" + INPUT_PASSWORD + "'");

					if (rs.next()) {
						USERNAME = rs.getString("username");
						PASSWORD = rs.getString("password");

						if (USERNAME.equalsIgnoreCase(INPUT_USERNAME)) {
							if (PASSWORD.equalsIgnoreCase(INPUT_PASSWORD)) {
								startActivity(new Intent(Login2.this, Dashboard.class));
								setRole(rs.getString("isStudent"));
								setUsername(rs.getString("FirstName"));
								setUserID(rs.getString("id"));
								Login2.this.finish();
								
							} else {
								ctr++;
								Toast.makeText(getBaseContext(),"Invalid password.", Toast.LENGTH_LONG).show();
								if (ctr == 3) {
									msg.setText("Incorrect password input (3x)!, \n application will close.");
									alertDialog.setTitle("Alert!");
									alertDialog.setIcon(android.R.drawable.ic_dialog_alert);
									alertDialog.setView(msg);
									alertDialog.setNegativeButton(android.R.string.ok,new DialogInterface.OnClickListener() {
										@Override
										public void onClick(DialogInterface arg0, int arg1) {
											finish();
										}
									});

								}} // end if-password check
						}}}

			} catch (SQLException e) {
				DatabaseConnector.Logger(getClass(), "doInBackground", e);
			} 

			return null;
		}

		protected void onPostExecute(String postExecute) {
			if (progressDialog.isShowing()) {
				progressDialog.dismiss();
			}

		}
	}
}